import asyncio
import re
from typing import Any, List

from aiohttp.client import ClientSession

from app.bot.utils.logger import log

from .utils import TempMailException, check_response


class FirstMail:
    def __init__(
        self,
        token: str,
    ) -> None:
        self.session = ClientSession()
        self.session.headers.update(
            {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0",
                "Content-Type": "application/json",
            }
        )
        self.token = token

    @check_response()
    async def _make_request(self, method: str, url: str, **kwargs) -> dict:
        try:
            async with await self.session.request(method, url, **kwargs) as response:
                return await response.json(content_type=None)
        except Exception as e:
            raise TempMailException(type(e).__name__, str(e))

    async def create_mail_box(self) -> tuple[str | None, str | None]:
        """Получаем адрес почты"""

        data = {
            "type": "3",
            "token": self.token,
        }

        response = await self._make_request(
            "post", "https://api-tools.firstmail.ltd/lk/get/email/", data=data
        )
        try:
            login, password = response["login"].split(":")
        except (IndexError, KeyError, TypeError):
            log.info(
                f"Не удалось получить временную почту. JSON ответ сервера: {response}"
            )
            login, password = None, None

        return login, password

    async def get_message(self, login: str, password: str) -> dict:

        data = {
            "username": login,
            "password": password,
            "token": self.token,
        }

        response = await self._make_request(
            "post", "https://api-tools.firstmail.ltd/mail/get/one", data=data
        )

        return response

    async def get_code_from_temp_mail(self, login: str, password: str) -> bool | Any:
        """Получаем код с временной почты"""

        retries = 0
        log.info("Жду код с временной почты")
        while True:
            await asyncio.sleep(5)
            mail = await self.get_message(login, password)
            if "Let's verify" in mail.get("subject"):
                letter_body = mail.get("message").replace(" ", "")
                code_result = re.findall(r"(\d{6,})", letter_body)
                log.info("Код получен")
                return code_result[0]
            retries += 1
            if retries > 10:
                log.error(f"Не смог получить код после {retries} попыток")
                return False
            return False
